package com.insight.service;

import com.insight.entity.DataSource;
import com.insight.entity.MetadataColumn;
import com.insight.entity.MetadataTable;
import com.insight.repository.MetadataColumnRepository;
import com.insight.repository.MetadataTableRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * T102: MetadataQueryService实现
 * 元数据查询服务,支持分页查询和多维度筛选
 *
 * 功能特性:
 * 1. 按数据源查询(分页)
 * 2. 按Schema查询(分页)
 * 3. 按表类型查询
 * 4. 按时间范围查询
 * 5. 列查询(分页)
 * 6. 统计查询(count)
 *
 * @author Insight Team
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class MetadataQueryService {

    private final MetadataTableRepository tableRepository;
    private final MetadataColumnRepository columnRepository;

    // ==================== 按数据源查询 ====================

    /**
     * 查询所有表(分页)
     * 用于空关键词搜索场景
     *
     * @param pageable 分页参数
     * @return 表元数据分页结果
     */
    public Page<MetadataTable> queryAllTables(Pageable pageable) {
        log.debug("Querying all tables with pagination");
        return tableRepository.findAll(pageable);
    }

    /**
     * 查询指定数据源的所有表(分页)
     *
     * @param dataSource 数据源
     * @param pageable   分页参数
     * @return 表元数据分页结果
     */
    public Page<MetadataTable> queryTablesByDataSource(DataSource dataSource, Pageable pageable) {
        log.debug("Querying tables by data source: dataSourceId={}", dataSource.getId());
        return tableRepository.findByDataSource(dataSource, pageable);
    }

    /**
     * 查询指定数据源ID的所有表(分页)
     *
     * @param dataSourceId 数据源ID
     * @param pageable     分页参数
     * @return 表元数据分页结果
     */
    public Page<MetadataTable> queryTablesByDataSourceId(Long dataSourceId, Pageable pageable) {
        log.debug("Querying tables by data source ID: dataSourceId={}", dataSourceId);
        return tableRepository.findByDataSourceId(dataSourceId, pageable);
    }

    // ==================== 按Schema查询 ====================

    /**
     * 查询指定数据源和Schema的所有表(分页)
     *
     * @param dataSource 数据源
     * @param schema     Schema名称
     * @param pageable   分页参数
     * @return 表元数据分页结果
     */
    public Page<MetadataTable> queryTablesByDataSourceAndSchema(
            DataSource dataSource, String schema, Pageable pageable) {
        log.debug("Querying tables by data source and schema: dataSourceId={}, schema={}",
                dataSource.getId(), schema);
        return tableRepository.findByDataSourceAndTableSchema(dataSource, schema, pageable);
    }

    // ==================== 按表类型查询 ====================

    /**
     * 查询指定表类型的所有表
     *
     * @param tableType 表类型 (TABLE, VIEW, etc.)
     * @return 表元数据列表
     */
    public List<MetadataTable> queryTablesByType(String tableType) {
        log.debug("Querying tables by type: tableType={}", tableType);
        return tableRepository.findByTableType(tableType);
    }

    /**
     * 查询指定数据源和表类型的所有表
     *
     * @param dataSource 数据源
     * @param tableType  表类型
     * @return 表元数据列表
     */
    public List<MetadataTable> queryTablesByDataSourceAndType(DataSource dataSource, String tableType) {
        log.debug("Querying tables by data source and type: dataSourceId={}, tableType={}",
                dataSource.getId(), tableType);
        return tableRepository.findByDataSourceAndTableType(dataSource, tableType);
    }

    // ==================== 按时间范围查询 ====================

    /**
     * 查询指定时间范围内更新的表
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 表元数据列表
     */
    public List<MetadataTable> queryTablesByUpdatedAtRange(LocalDateTime startTime, LocalDateTime endTime) {
        log.debug("Querying tables by updated_at range: startTime={}, endTime={}", startTime, endTime);
        return tableRepository.findByUpdatedAtBetween(startTime, endTime);
    }

    /**
     * 查询指定数据源在时间范围内更新的表
     *
     * @param dataSource 数据源
     * @param startTime  开始时间
     * @param endTime    结束时间
     * @return 表元数据列表
     */
    public List<MetadataTable> queryTablesByDataSourceAndUpdatedAtRange(
            DataSource dataSource, LocalDateTime startTime, LocalDateTime endTime) {
        log.debug("Querying tables by data source and updated_at range: dataSourceId={}, startTime={}, endTime={}",
                dataSource.getId(), startTime, endTime);
        return tableRepository.findByDataSourceAndUpdatedAtBetween(dataSource, startTime, endTime);
    }

    /**
     * 查询指定表在时间范围内更新的列
     *
     * @param table     表
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 列元数据列表
     */
    public List<MetadataColumn> queryColumnsByTableAndUpdatedAtRange(
            MetadataTable table, LocalDateTime startTime, LocalDateTime endTime) {
        log.debug("Querying columns by table and updated_at range: tableId={}, startTime={}, endTime={}",
                table.getId(), startTime, endTime);
        return columnRepository.findByTableAndUpdatedAtBetween(table, startTime, endTime);
    }

    // ==================== 列查询 ====================

    /**
     * 查询指定表的所有列(分页)
     *
     * @param table    表
     * @param pageable 分页参数
     * @return 列元数据分页结果
     */
    public Page<MetadataColumn> queryColumnsByTable(MetadataTable table, Pageable pageable) {
        log.debug("Querying columns by table: tableId={}", table.getId());
        return columnRepository.findByTable(table, pageable);
    }

    /**
     * 查询指定表ID的所有列(分页)
     *
     * @param tableId  表ID
     * @param pageable 分页参数
     * @return 列元数据分页结果
     */
    public Page<MetadataColumn> queryColumnsByTableId(Long tableId, Pageable pageable) {
        log.debug("Querying columns by table ID: tableId={}", tableId);
        return columnRepository.findByTableId(tableId, pageable);
    }

    // ==================== 统计查询 ====================

    /**
     * 统计指定数据源的表数量
     *
     * @param dataSource 数据源
     * @return 表数量
     */
    public long countTablesByDataSource(DataSource dataSource) {
        log.debug("Counting tables by data source: dataSourceId={}", dataSource.getId());
        return tableRepository.countByDataSource(dataSource);
    }

    /**
     * 统计指定数据源ID的表数量
     *
     * @param dataSourceId 数据源ID
     * @return 表数量
     */
    public long countTablesByDataSourceId(Long dataSourceId) {
        log.debug("Counting tables by data source ID: dataSourceId={}", dataSourceId);
        return tableRepository.countByDataSourceId(dataSourceId);
    }

    /**
     * 统计指定数据源和Schema的表数量
     *
     * @param dataSource 数据源
     * @param schema     Schema名称
     * @return 表数量
     */
    public long countTablesByDataSourceAndSchema(DataSource dataSource, String schema) {
        log.debug("Counting tables by data source and schema: dataSourceId={}, schema={}",
                dataSource.getId(), schema);
        return tableRepository.countByDataSourceAndTableSchema(dataSource, schema);
    }

    /**
     * 统计指定表的列数量
     *
     * @param table 表
     * @return 列数量
     */
    public long countColumnsByTable(MetadataTable table) {
        log.debug("Counting columns by table: tableId={}", table.getId());
        return columnRepository.countByTable(table);
    }
}
